package cn.cuilan.encrypt;

import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class App {

    // 秘钥
    private static final String AES_KEY = "/eS9zFpsHyz4PSKb44aaJw==";

    /**
     * AES加密
     *
     * @param srcPathFileName     源文件全路径
     * @param encryptPathFileName 加密后文件存放路径
     */
    public static void aesEncryptFile(String srcPathFileName, String encryptPathFileName) {
        long start = System.currentTimeMillis();
        byte[] bytes = FileReadWriteUtils.readFileBytes(srcPathFileName);
        byte[] encryptData = AESUtils.encrypt(bytes, AESUtils.base64DecodeKey(AES_KEY));
        FileReadWriteUtils.writeFile(encryptData, encryptPathFileName);
        System.out.println("加密耗时: " + (System.currentTimeMillis() - start) + "毫秒.");
    }

    /**
     * AES解密
     *
     * @param encryptPathFileName 加密文件全路径
     * @param srcPathFileName     解密后的文件存放路径
     */
    public static void aesDecryptFile(String encryptPathFileName, String srcPathFileName) {
        long start = System.currentTimeMillis();
        byte[] bytes = FileReadWriteUtils.readFileBytes(encryptPathFileName);
        byte[] decryptData = AESUtils.decrypt(bytes, AESUtils.base64DecodeKey(AES_KEY));
        FileReadWriteUtils.writeFile(decryptData, srcPathFileName);
        System.out.println("解密耗时: " + (System.currentTimeMillis() - start) + "毫秒.");
    }

    /**
     * 读取秘钥文件
     *
     * @param secretKeyPath 秘钥全路径
     * @return 返回秘钥二进制
     */
    public static byte[] readKeyFile(String secretKeyPath) {
        return FileReadWriteUtils.readFileBytes(secretKeyPath);
    }

    /**
     * 将秘钥保存为文件
     */
    public static void writeKeyFile(String secretKey, String secretKeyPath) {
        byte[] key = secretKey.getBytes();
        FileReadWriteUtils.writeFile(key, secretKeyPath);
    }

    public static void printTitle() {
        System.out.println("|===========================================|");
        System.out.println("|                AES加密工具                |");
        System.out.println("|===========================================|");
        System.out.println("|  模 式  | 生成秘钥|  加密 |  解密 |  退出 |");
        System.out.println("|-------------------------------------------|");
        System.out.println("|  指 令  |    0    |   1   |   2   |   3   |");
        System.out.println("|===========================================|");
        System.out.println("$请输入指令:");
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in, "UTF-8");
        while (true) {
            printTitle();
            String module = scanner.nextLine();
            int enOrDe;
            try {
                enOrDe = Integer.parseInt(module);
                if (enOrDe < 0 || enOrDe > 3) {
                    throw new RuntimeException();
                }
            } catch (Exception e) {
                System.err.println("Error: 模式选择不正确！" + module);
                System.out.println();
                System.out.println();
                continue;
            }

            // 生成秘钥
            if (enOrDe == 0) {
                System.out.println("$请输入秘钥存放的路径(包含文件全名称):");
                String keyPath = scanner.nextLine();
                String keyWithBase64 = AESUtils.generateRandomKeyWithBase64();
                FileReadWriteUtils.writeFile(keyWithBase64.getBytes(), keyPath);
                System.out.println("[INFO] - 秘钥创建成功.");
                System.out.println("[INFO] - 秘钥路径：" + keyPath);
                System.out.println();
                System.out.println();
            }

            // 加密
            if (enOrDe == 1) {
                System.out.println("$请输入加密文件(包含路径):");
                String path = scanner.nextLine();
                System.out.println("$请输入秘钥路径(包含文件全名称):");
                String keyPath = scanner.nextLine();
                System.out.println("[INFO] - 开始加密...");
                System.out.println("[INFO] - 文件路径: " + path);
                System.out.println("[INFO] - 秘钥路径: " + keyPath);
                int i = path.lastIndexOf(".");
                System.out.println(path.substring(0, i));
                String encryptPath = path.substring(0, i) + ".encrypt";
                aesEncryptFile(path, encryptPath);
                System.out.println("[INFO] - 加密完成...");
                System.out.println("[INFO] - 加密文件保存路径: " + encryptPath);
                System.out.println();
                System.out.println();
            }

            // 解密
            if (enOrDe == 2) {
                System.out.println("$请输入待解密文件(包含路径):");
                String encryptPath = scanner.nextLine();
                System.out.println("$请输入解密后存放路径(路径+文件名):");
                String srcPath = scanner.nextLine();
                System.out.println("$请输入秘钥路径(包含文件全名称):");
                String keyPath = scanner.nextLine();
                System.out.println("[INFO] - 开始解密...");
                System.out.println("[INFO] - 待解密文件路径: " + encryptPath);
                System.out.println("[INFO] - 解密后文件路径: " + srcPath);
                System.out.println("[INFO] - 秘钥路径: " + keyPath);
                aesDecryptFile(encryptPath, srcPath);
                System.out.println("[INFO] - 解密完成...");
                System.out.println("[INFO] - 解密文件保存路径: " + srcPath);
                System.out.println();
                System.out.println();
            }

            // 退出
            if (enOrDe == 3) {
                scanner.close();
                // 程序结束
                System.exit(0);
            }
        }
    }
}